package com.hilinos.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hilinos.base.common.Constant;
import com.hilinos.base.common.config.ServerConfig;
import com.hilinos.base.user.entity.dto.TokenDto;
import com.hilinos.base.user.entity.pojo.UserInfoPoJo;
import com.hilinos.base.mapper.IUserInfoMapper;
import com.hilinos.base.service.UserInfoService;
import com.hilinos.common.common.ReturnCode;
import com.hilinos.common.entity.BaseQo;
import com.hilinos.common.util.AssertUtils;
import com.hilinos.common.util.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author hilinos
 * @since 2022-03-08
 */
@Service
public class UserInfoServiceImpl extends ServiceImpl<IUserInfoMapper, UserInfoPoJo> implements UserInfoService {

    private final static String RK_TOKEN = "com:hilinos:user:token:%s";

    @Autowired
    private RedisTemplate<String, UserInfoPoJo> redisTemplate;

    @Autowired
    private ServerConfig serverConfig;

    public static String getRkToken(String token) {
        return String.format(RK_TOKEN, token);
    }

    @Override
    public String genToken(UserInfoPoJo userInfoPoJo) {
        return RandomUtils.getABSRandomString();
    }

    @Override
    public void saveToken(UserInfoPoJo userInfoPoJo, String token, Long expireTime) {
        redisTemplate.opsForValue().set(getRkToken(token), userInfoPoJo, expireTime, TimeUnit.SECONDS);
    }

    @Override
    public UserInfoPoJo checkToken(String token) {
        // 由于redis事务太麻烦，就简单处理，优先设置token过期时间，再去查询。如果token已经过期了，也不会有什么影响
        freshToken(token, serverConfig.getTokenExpireTime());
        UserInfoPoJo userInfoPoJo = redisTemplate.opsForValue().get(getRkToken(token));
        AssertUtils.isNotEmpty(userInfoPoJo, ReturnCode.AUTH_ERROR);
        return userInfoPoJo;
    }

    @Override
    public void freshToken(String token, Long expireTime) {
        redisTemplate.expire(getRkToken(token), expireTime, TimeUnit.SECONDS);
    }

    @Override
    public UserInfoPoJo getDetail(String userId, String userType, String appid) {
        QueryWrapper<UserInfoPoJo> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(UserInfoPoJo::getUserId, userId).eq(UserInfoPoJo::getAppid, appid)
                .eq(UserInfoPoJo::getUserType, userType);
        return getOne(queryWrapper);
    }

    @Override
    public TokenDto getTokenInfo(String token) {
        AssertUtils.isRex(redisTemplate.hasKey(getRkToken(token)), ReturnCode.AUTH_ERROR);
        return TokenDto.builder().tokenExpireTime(redisTemplate.getExpire(getRkToken(token), TimeUnit.SECONDS)).token(token).build();
    }

    @Override
    public void removeToken(String token) {
        redisTemplate.delete(getRkToken(token));
    }

    @Override
    public boolean isSuperAdmin(String token) {
        UserInfoPoJo userInfo = checkToken(token);
        return Constant.SU_USER_TYPE_ADMIN.equals(userInfo.getUserType());
    }

    public void editUser(UserInfoPoJo userInfoPoJo) {
//        UpdateWrapper<UserInfoPoJo> updateWrapper = new UpdateWrapper<>();
//        updateWrapper.lambda()
//                .set(UserInfoPoJo::getUserType, userInfoPoJo.getUserType())
//                .set(UserInfoPoJo::getUserTypeName, userInfoPoJo.getUserTypeName())
//                .set(UserInfoPoJo::getUserMobile, userInfoPoJo.getUserMobile())
//                .set(UserInfoPoJo::getUserDisplayName, userInfoPoJo.getUserDisplayName())
//
//                .eq(UserInfoPoJo::getAppid, userInfoPoJo.getAppid())
//                .eq(UserInfoPoJo::getUserId, userInfoPoJo.getUserId());
        saveOrUpdate(userInfoPoJo);
    }

    @Override
    public UserInfoPoJo delDetail(String userId, String appid) {
        BaseQo<UserInfoPoJo, UserInfoPoJo, UserInfoPoJo> qo = new BaseQo<>();
        qo.setE(UserInfoPoJo.builder().userId(userId).appid(appid).build());
        return getOne(qo.queryWrapper());
    }

    @Override
    public IPage<UserInfoPoJo> userList(UserInfoPoJo userInfoPoJo,Page<UserInfoPoJo> page) {
        return null;
    }

}